#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<sys/ioctl.h>
#include<pthread.h>
#include<fcntl.h>
#include<linux/input.h>
#include<strings.h>

#define MAXLINE 80
#define SERV_PORT 8100
#define test_bit(bit, array)    (array[bit/8] & (1<<(bit%8)))
#define RETRY_NUM 4

char device[] = "/dev/input/event0";
static int fd= -1;
int date_config_flag = 0;

static int init_device(void)
{
	  char devname[256];
	  static char keypad[] = "Keypad";
	  struct input_id device_info;
	  unsigned int yalv, i, result;
	  unsigned char evtype_bitmask[EV_MAX/8 + 1];

	  result = 0;
	  for (i = 0; i < RETRY_NUM; i++) {
		printf("trying to open %s ...\n", device);
		if ((fd=open(device,O_RDONLY)) < 0) {
		  break;
		}
		memset(devname, 0x0, sizeof(devname));
		if (ioctl(fd, EVIOCGNAME(sizeof(devname)), devname) < 0) {
		  printf("%s evdev ioctl error!\n", device);
		} else {
		  if (strstr(devname, keypad) != NULL) {
		    printf("Keypad device is %s\n", device);
		    result = 1;
		    break;
		  }
		}
		close(fd);
		device[16]++;
	  }
	  if (result == 0) {
		printf("can not find any Keypad device!\n");
		return -1;
	  }

	  ioctl(fd, EVIOCGBIT(0, sizeof(evtype_bitmask)), evtype_bitmask);
		
	  printf("Supported event types:\n");
	  for (yalv = 0; yalv < EV_MAX; yalv++) {
		if (test_bit(yalv, evtype_bitmask)) {
		  /* this means that the bit is set in the event types list */
		  printf("  Event type 0x%02x ", yalv);
	  	switch ( yalv)
		{
		case EV_SYN :
		  printf(" EV_SYN\n");
		  break;
		case EV_REL :
		  printf(" EV_REL\n");
		  break;
		case EV_KEY :
			printf(" EV_KEY\n");
			break;
		default:
		  printf(" Other event type: 0x%04hx\n", yalv);
		  break;
		}
		  
		}        
	  }
	  return 0;
}


int main(int argc, char *argv[])
{

	struct input_event data;
	struct sockaddr_in servaddr,servaddr1;
	int sockfd, sockfd1, n;
	char *buf;
	char str[INET_ADDRSTRLEN];
	
	socklen_t servaddr_len, servaddr_len1;
	sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	sockfd1 = socket(AF_INET, SOCK_DGRAM, 0);
	bzero(&servaddr, sizeof(servaddr));
	bzero(&servaddr1, sizeof(servaddr1));

	servaddr.sin_family = AF_INET;
	inet_pton(AF_INET, "127.0.0.1", &servaddr.sin_addr);
	servaddr.sin_port = htons(SERV_PORT);

	servaddr1.sin_family = AF_INET;
	inet_pton(AF_INET, "127.0.0.1", &servaddr1.sin_addr);
	servaddr1.sin_port = htons(8000);
	
	buf = (char*)malloc(10);
	
	if(init_device()<0) {
		printf("init error\n");
		return -1;
  	}

	

	for(;;)
	{

	    	read(fd,&data,sizeof(data));
	    	if(data.type == 0)
			continue;
		printf("%d.%06d ", data.time.tv_sec, data.time.tv_usec);
		printf("%d %d %d %s\n", data.type, data.code, data.value, (data.value == 0) ? "up" : "down");

		switch ( data.code)
		{
		case 13 :
			if(data.value == 1)
			{
				date_config_flag=1-date_config_flag;
				printf("date config mod\n");
				buf = "c";
				n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
			}
		    break;
		case 14 :
			if(data.value == 1)
			{
				if(date_config_flag)
				{
					printf(" add\n");
					buf = "a";
					n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
				}
				else
				{
					printf(" volume +\n");
					//buf = "*";
					buf = "m";
					n = sendto(sockfd1, buf, strlen(buf), 0, (struct sockaddr *)&servaddr1, sizeof(servaddr1));

				}
			}
		    break;
		case 15 :
			if(data.value == 1)
			{
				if(date_config_flag)
				{
					printf(" sub\n");
					buf = "s";
					n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
				}
				else
				{
					printf(" volume -\n");
					//buf = "/";
					buf = "w";
					n = sendto(sockfd1, buf, strlen(buf), 0, (struct sockaddr *)&servaddr1, sizeof(servaddr1));
					
				}
			}
			break;
		case 19 :
			if(data.value == 1)
			{
				if(date_config_flag)
				{
					printf(" offset\n");
					buf = "o";
					n = sendto(sockfd, buf, strlen(buf), 0, (struct sockaddr *)&servaddr, sizeof(servaddr));
					
				}
				else
				{
					printf(" next\n");
					buf = "p";
					n = sendto(sockfd1, buf, strlen(buf), 0, (struct sockaddr *)&servaddr1, sizeof(servaddr1));
				}
			}
			break;
		default:
		 printf(" Other event type\n" );
		 	break;
		}
		if (n == -1)
			perror("sendto error");
   	}

	free(buf);
	close(sockfd);

	return 0;
}
